home *** CD-ROM | disk | FTP | other *** search
/ ASME's Mechanical Engine…ing Toolkit 1997 December / ASME's Mechanical Engineering Toolkit 1997 December.iso / c_lang / ems_subs.msg < prev    next >
Text File  |  1989-04-23  |  8KB  |  329 lines

  1. Path: rutgers!ucsd!ames!killer!royf
  2. From: royf@killer.Dallas.TX.US (Roy Frederick)
  3. Newsgroups: comp.sys.ibm.pc
  4. Subject: EMS Routines for TurboC
  5. Date: 23 Apr 89 17:56:03 GMT
  6. Keywords: EMS TURBOC
  7.  
  8. These EMS access routines are in the public domain - no secrets,
  9. copyrights, or restrictions on use.  There really isn't much to them -
  10. but I use them in production data collection programs that run every
  11. day (at least I think these are the versions I am currently using!).
  12.  
  13. Three routines are included: Emstest.c, emstbl.c, emssubr.asm.  Also a
  14. header file etbl.h.  Emssubr.asm provides the lowest level access to
  15. EMS.  It is called by emstbl.c to provide access to tables of fixed
  16. length items with a total length limited by the amount of EMS present.
  17. The length of a single table item is limited to <= 16384 (EMS page
  18. length).  Space beyond the last item in an EMS page is wasted.
  19. Emstest.c demonstrates the use of emstbl.c.  The routines are set up
  20. for large model.
  21.  
  22. C routines have 4 col tabs; ASM , 8 
  23.  
  24. Etbl.h -------------------------------------------------------------
  25. /*
  26.  * Etbl.h -- Structure describing table in EMS
  27.  */
  28.  
  29. struct etbl {
  30.     int e_elen;                            /* Table entry length */
  31.     int e_ecnt;                            /* Table entry count */
  32.     int e_efrm;                            /* Frame to be used */
  33.     int e_ecur;                            /* Last assigned entry number */
  34.     int e_ecpf;                            /* Entry count per page */
  35.     int e_pgs;                            /* Pages allocated */
  36.     int e_hand;                            /* EMS Handle */
  37. } ;
  38.  
  39. void far * far etmap(struct etbl far *, int);
  40. int far etinit(struct etbl far *);
  41. void far etclose(struct etbl far *);
  42.  
  43. Emstest.c --------------------------------------------------------------------
  44. /*
  45.  * Emstest.c -- EMS Table Routines Test Pgm
  46.  */
  47.  
  48. #include <dos.h>
  49. #include <mem.h>
  50. #include <alloc.h>
  51. #include <stdio.h>
  52. #include <stdlib.h>
  53. #include <conio.h>
  54.  
  55. #include "etbl.h"
  56.  
  57. struct etbl et1 = { 100, 1000, 1, 0, 0, 0 } ;
  58.  
  59. main()
  60. {
  61.     int i;
  62.     int far *q;
  63.  
  64.     etinit(&et1);
  65.  
  66.     for (i = 1; i <= 1000; i++) {
  67.         q = etmap(&et1, i);
  68.         if (q == 0L)
  69.             err("Etmap failed for %d", i);
  70.         *q = i;
  71.     }
  72.     for (i = 1; i <= 1000; i++) {
  73.         q = etmap(&et1, i);
  74.         if (q == 0L)
  75.             err("Etmap failed for %d", i);
  76.         if (*q != i)
  77.             err("Data error - exp %d got %d", i, *q);
  78.     }
  79.     etclose(&et1);
  80.     err("Test successful");
  81. }
  82.  
  83. err(s)
  84. const char *s;
  85. {
  86.     va_list argptr;
  87.     va_start(argptr, s);
  88.     fprintf(stderr, "Terminated: ");
  89.     vfprintf(stderr, s, argptr);
  90.     fprintf(stderr, "\n");
  91.     exit(2);
  92. }
  93.  
  94. Emstbl.c ----------------------------------------------------------------
  95. /*
  96.  * Emstbl -- EMS Table Routines
  97.  */
  98.  
  99. #include <dos.h>
  100. #include <mem.h>
  101. #include <alloc.h>
  102. #include <stdio.h>
  103. #include <stdlib.h>
  104. #include <conio.h>
  105.  
  106. #include "etbl.h"
  107.  
  108. static int eseg;                        /* EMS Segment Address */
  109.  
  110. extern int ems_err;
  111.  
  112. int far etinit(e)
  113. struct etbl far *e;
  114. {
  115.     int i;
  116.  
  117.     if (ems_verify() == 0)
  118.         err("No EMS driver found");
  119.  
  120.     eseg = ems_getframe();
  121.     e->e_ecpf = 16384 / e->e_elen;
  122.     e->e_pgs = (e->e_ecnt + e->e_ecpf - 1) / e->e_ecpf;
  123.     e->e_ecnt = e->e_pgs * e->e_ecpf;
  124.  
  125.     if ((e->e_hand = ems_alloc(e->e_pgs)) == 0)
  126.         err("Not enough EMS available");
  127.     for (i = 0; i < e->e_pgs; i++) {
  128.         if (ems_map(e->e_efrm, e->e_hand, i) == 0)
  129.             err("EMS_MAP failed err %02x  handle %04X  page %02X",
  130.                 ems_err, e->e_hand, i);
  131.         memset(MK_FP(eseg, (e->e_efrm << 14)), 0, 16384);
  132.     }
  133.  
  134.     e->e_ecur = 0;
  135.     return(0);
  136. }
  137.  
  138. void far * far etmap(e, ndx)
  139. struct etbl far *e;
  140. int ndx;
  141. {
  142.     int i, j, pg;
  143.     j = ndx - 1;
  144.     i = j / e->e_ecpf;
  145.     j = j % e->e_ecpf;
  146.     pg = e->e_efrm;
  147.     if (ems_map(pg, e->e_hand, i) == 0)
  148.         err("EMS_MAP failed err %02x  handle %04X  page %02X",
  149.             ems_err, e->e_hand, i);
  150.     return(MK_FP((eseg + (pg << 10)), (j * e->e_elen)));
  151. }
  152.  
  153. void far etclose(e)
  154. struct etbl far *e;
  155. {
  156.     ems_free(e->e_hand);
  157.     e->e_elen = e->e_ecur = e->e_ecnt = e->e_hand = 0;
  158. }
  159.  
  160.  
  161. Emssubr.asm -----------------------------------------------------------
  162. ----assemble with TASM /W2 /MX emssubr -------------------------------
  163.                 PAGE ,132
  164.                 TITLE Expanded Memory Access Routines
  165.  
  166.         .MODEL    LARGE,C
  167.  
  168.                 PUBLIC  ems_err
  169.                 PUBLIC  ems_verify
  170.                 PUBLIC  ems_alloc
  171.                 PUBLIC  ems_map
  172.                 PUBLIC  ems_free
  173.                 PUBLIC  ems_getframe
  174.                 PUBLIC  ems_pagecnt
  175.  
  176.         LOCALS    LL
  177.  
  178.                 .DATA
  179.  
  180. emname        db    'EMMXXXX0'    ; name of ems driver
  181.  
  182. ems_err        dw    0
  183.  
  184.                 .CODE
  185.  
  186.                 SUBTTL ems_verify
  187.                 PAGE +
  188.  
  189. ems_verify    PROC    uses DS SI DI
  190.         mov    ax, DGROUP
  191.         mov    ds, ax
  192.  
  193.         mov    ax, 0          ; check if int vect 67 set up
  194.         mov    es, ax
  195.         mov    ax, es:[4*67h+2]
  196.         or    ax, ax        ; segment non zero ?
  197.         jz    LL01        ; if not
  198.         mov    es, ax
  199.  
  200.         mov    di, 10        ; offset to driver name
  201.         mov    si, offset emname
  202.         mov    cx, 8
  203.         cld
  204.         rep    cmpsb        ; check driver name
  205.         jne    LL01
  206.  
  207.         mov    ax, 1
  208.         jmp    short LL02
  209.  
  210. LL01:        mov    ax, 0ffh    ; no driver code
  211.         mov    [ems_err], ax
  212.         xor    ax, ax        ; zero ret code = bad
  213.         
  214. LL02:        ret
  215.  
  216. ems_verify    ENDP
  217.     
  218.  
  219.                 SUBTTL ems_alloc
  220.                 PAGE +
  221.  
  222. ems_alloc    PROC    uses DS
  223.         arg    pgcnt:word
  224.         mov    ax, DGROUP
  225.         mov    ds, ax
  226.  
  227.                 mov    bx, [pgcnt]    ; get number of pages to allocate
  228.                 mov    ah, 43H        ; allocate space
  229.                 int    67H
  230.                 mov    byte ptr [ems_err], ah
  231.                 or    ah, ah        ; ah is zero if call succeeded
  232.                 jnz    LL01
  233.         mov    ax, dx        ; return handle
  234.                 jmp    short LL02
  235. LL01:
  236.                 xor    ax, ax
  237. LL02:
  238.                 ret
  239. ems_alloc    ENDP
  240.  
  241.                 SUBTTL ems_map
  242.                 PAGE +
  243.  
  244. ems_map        PROC    uses DS
  245.         arg    phys:word,handle:word,lpage:word
  246.         mov    ax, DGROUP
  247.         mov    ds, ax
  248.  
  249.         mov    ax, [phys]    ; get phys page slot
  250.         mov    dx, [handle]    ; get handle number
  251.         mov    bx, [lpage]    ; get logical page number
  252.                 mov    ah, 44H        ; map page
  253.                 int    67H
  254.                 mov    byte ptr [ems_err], ah
  255.                 or    ah, ah        ; see if ok
  256.                 jnz    LL01
  257.  
  258.                 mov    ax, 1
  259.                 jmp    short LL02
  260. LL01:
  261.                 xor    ax, ax
  262. LL02:
  263.                 ret
  264. ems_map        ENDP
  265.                 
  266.                 SUBTTL ems_free
  267.                 PAGE +
  268.  
  269. ems_free    PROC
  270.         arg    handle:word
  271.  
  272.                 mov    dx, [handle]
  273.                 mov    ah, 45H
  274.                 int    67H
  275.         xor    ax, ax
  276.  
  277.                 ret
  278. ems_free    ENDP
  279.  
  280.                 SUBTTL ems_getframe
  281.                 PAGE +
  282.  
  283. ems_getframe    PROC    uses DS        ; sets AX to EMS page frame
  284.         mov    ax, DGROUP
  285.         mov    ds, ax
  286.  
  287.                 mov    ah, 41H        ; get frame seq
  288.                 int    67H
  289.                 mov    byte ptr [ems_err], ah
  290.                 or    ah, ah        ; ah is zero if call succeeded
  291.                 jnz    LL01
  292.                 mov    ax, bx        ; return page frame in ax
  293.                 jmp    short LL02
  294. LL01:
  295.                 xor    ax, ax
  296. LL02:
  297.                 ret
  298. ems_getframe    ENDP
  299.  
  300.                 SUBTTL ems_pagecnt
  301.                 PAGE +
  302.  
  303. ems_pagecnt    PROC    uses DS        ; sets AX to EMS page frame
  304.         mov    ax, DGROUP
  305.         mov    ds, ax
  306.  
  307.                 mov    ah, 42H        ; get ems page count
  308.                 int    67H
  309.                 mov    byte ptr [ems_err], ah
  310.                 or    ah, ah        ; see if ok
  311.                 jnz    LL01
  312.  
  313.                 mov    ax, bx        ; return page count
  314.                 jmp    short LL02
  315. LL01:
  316.                 xor    ax, ax
  317. LL02:
  318.                 ret
  319. ems_pagecnt    ENDP
  320.  
  321.                 END
  322. -----------------------------------------------------------------------------
  323.  
  324.  
  325. Roy Frederick (royf@killer.UUCP)
  326. Dallas County Data Services  (214) 749-6340
  327. 504 Records Bldg.
  328. Dallas, TX 75202
  329.